import json
import redis
import time
from PySide6.QtCore import QThread, Signal, QObject
from utils.redis_pubsub import RedisSubscribe
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QTextEdit


# Redis发布类
class RedisPublisher:
    def __init__(self):
        self.redis_config = RedisSubscribe.get_redis_config()
        if not self.redis_config:
            raise ValueError('Redis配置参数获取失败')
        self.redis_conn = redis.Redis(**self.redis_config)
        self.redis_conn.ping()  # 测试连接

    def publish(self, channel, data):
        """发布消息到指定频道"""
        if isinstance(data, dict):
            data_str = json.dumps(data)
        else:
            data_str = str(data)
        return self.redis_conn.publish(channel, data_str)


# 测试窗口
class PubSubTestWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Redis发布订阅测试")
        self.setGeometry(100, 100, 600, 400)

        # 初始化发布者
        try:
            self.publisher = RedisPublisher()
        except ValueError as e:
            print(e)
            self.publisher = None

        # 初始化订阅者
        try:
            self.subscriber = RedisSubscribe()
            self.subscriber.signal.connect(self.on_message_received)
            self.subscriber.start()
        except ValueError as e:
            print(e)
            self.subscriber = None

        self.init_ui()

    def init_ui(self):
        layout = QVBoxLayout()

        # 接收消息显示区域
        self.receive_area = QTextEdit()
        self.receive_area.setReadOnly(True)
        self.receive_area.setPlaceholderText("接收的消息将显示在这里...")
        layout.addWidget(self.receive_area)

        # 测试按钮
        self.test_btn1 = QPushButton("发送测试消息1")
        self.test_btn1.clicked.connect(self.send_test_message1)
        layout.addWidget(self.test_btn1)

        self.test_btn2 = QPushButton("发送测试消息2")
        self.test_btn2.clicked.connect(self.send_test_message2)
        layout.addWidget(self.test_btn2)

        self.test_btn3 = QPushButton("发送测试消息3")
        self.test_btn3.clicked.connect(self.send_test_message3)
        layout.addWidget(self.test_btn3)

        self.setLayout(layout)

    def on_message_received(self, data):
        """处理接收到的消息"""
        self.receive_area.append(f"收到消息: {json.dumps(data, ensure_ascii=False, indent=2)}")
        # 滚动到底部
        self.receive_area.verticalScrollBar().setValue(
            self.receive_area.verticalScrollBar().maximum()
        )

    def send_test_message1(self):
        """发送测试消息1"""
        if not self.publisher:
            self.receive_area.append("发布者初始化失败，无法发送消息")
            return

        test_data = {'process': 'start', 'current_vin': 'LFPH4APP2S1A57140'}
        result = self.publisher.publish('operation_channel', test_data)
        self.receive_area.append(f"发送测试消息1: {'成功' if result else '失败'}")

    def send_test_message2(self):
        """发送测试消息2"""
        if not self.publisher:
            self.receive_area.append("发布者初始化失败，无法发送消息")
            return

        test_data = {'process': 'end', 'current_vin': 'LFPH4APP2S1A57140',
                     'captured_list': ['LFPH4APP2S1A57140', 'LFPH4APP8S1A57188', 'LFPH4APP4S1A57186',
                                       'LFPH4APP7S1A57182'], 'abnormal_list': ['LFPH4APP7S1A57098'],
                     'captured_count': 4, 'abnormal_count': 1, 'ocr_vin': 'LFPH4APP2S1A57140',
                     'jpg_path': 'http://127.0.0.1:8000/media/vin/20250903/21c1c823-e757-47e0-a583-613d77d737f7.jpg',
                     'ocr_vin_result': {'ocr_vin': 'LFPH4APP2S1A57140', 'ocr_vin_judge': '2', 'ocr_vin_result': '一致'},
                     'state': 'failure'}
        result = self.publisher.publish('operation_channel', test_data)
        self.receive_area.append(f"发送测试消息2: {'成功' if result else '失败'}")

    def send_test_message3(self):
        """发送测试消息3"""
        if not self.publisher:
            self.receive_area.append("发布者初始化失败，无法发送消息")
            return

        test_data = {'process': 'upload', 'current_vin': 'LFPH4APP2S1A57140', 'status': 'failure'}
        result = self.publisher.publish('operation_channel', test_data)
        self.receive_area.append(f"发送测试消息3: {'成功' if result else '失败'}")

    def closeEvent(self, event):
        """窗口关闭时停止订阅线程"""
        if self.subscriber and self.subscriber.isRunning():
            self.subscriber.stop()
        event.accept()


if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    window = PubSubTestWindow()
    window.show()
    sys.exit(app.exec())
